package com.kermel.andromeda.data;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.UUID;

import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;

import com.kermel.common.util.DateTimeUtils;
import com.kermel.common.util.RingtoneUtils;
import com.kermel.common.util.StringUtils;

public class Alarm implements Parcelable {
    
    public static final long UNKNOWN_TRIGGER_TIME = -1;
    public static final int UNKNOWN_ALARM_NOTIFICATION_ID = -1;
    
    public String name = StringUtils.EMPTY;
    public boolean enabled = true;
    public boolean vibrate = true;
    public long triggerTime;
    public UUID uuid;
    public long rowID;
    public String ringtoneUriString;
    public String ringtoneTitle;

    public Alarm() {
        triggerTime = initializeTriggerTime();
        uuid = UUID.randomUUID();
    }
    
    public long initializeTriggerTime() {
        long alarmTriggerTime = 0;
        
        Calendar rightNow = Calendar.getInstance();
        rightNow.add(Calendar.MINUTE, 1);
        alarmTriggerTime = rightNow.getTimeInMillis();
        
        return alarmTriggerTime;
    }
    
    @Override
    public String toString() {
        StringBuffer result = new StringBuffer();
        
        result.append("\n    rowID: ").append(rowID);
        result.append("\n    name: ").append(name);
        result.append("\n    enabled: ").append(enabled);
        result.append("\n    vibrate: ").append(vibrate);
        result.append("\n    triggerTime: ").append(triggerTime);
        result.append(" [").append(DateTimeUtils.timeInMillisecondsToDateStringFull(triggerTime)).append("]");
        result.append("\n    ringtoneTitle: ").append(ringtoneTitle);
        result.append("\n    uuid: ").append(uuid.toString());
        result.append("\n");
        
        return result.toString();
    }
    
    public static String triggerTimeAsDateStringSimple(long triggerTime) {
        // TODO: Does this need to use a different pattern if we're not using military time?
        SimpleDateFormat formatter = new SimpleDateFormat(DateTimeUtils.HOURS_MINUTES_DATE_FORMAT_PATTERN);
        Date date = DateTimeUtils.timeInMillisecondsToDate(triggerTime);
        return formatter.format(date);
    }
    
    public UUID getUUID() {
        return uuid;
    }
    
    public int describeContents() {
        return 0;
    }
    
    @Override
    public boolean equals(Object otherObject) {
        boolean result = false;
        
        if (otherObject != null) {
            if (otherObject instanceof Alarm) {
                Alarm otherAlarm = (Alarm)otherObject;
                
                result = namesAreEqual(otherAlarm) &&
                         ringtoneUriStringsAreEqual(otherAlarm) &&
                         (enabled == otherAlarm.enabled) &&
                         (vibrate == otherAlarm.vibrate) &&
                         (triggerTime == otherAlarm.triggerTime) &&
                         (rowID == otherAlarm.rowID) &&
                         uuidValuesAreEqual(otherAlarm);
            }
        }
        
        return result;
    }
    
    private boolean namesAreEqual(Alarm otherAlarm) {
        boolean result = false;
        
        if (name == null)
            result = otherAlarm.name == null;
        else
            result = name.equals(otherAlarm.name);
        
        return result;
    }
    
    private boolean ringtoneUriStringsAreEqual(Alarm otherAlarm) {
        boolean result = false;
        
        if (ringtoneUriString == null)
            result = otherAlarm.ringtoneUriString == null;
        else
            result = ringtoneUriString.equals(otherAlarm.ringtoneUriString);
        
        return result;
    }
    
    private boolean uuidValuesAreEqual(Alarm otherAlarm) {
        if (otherAlarm == null)
            return false;
        
        if (uuid == null)
            return otherAlarm.uuid == null;
        
        boolean result = false;
        if (otherAlarm != null) {
            UUID otherUUID = otherAlarm.uuid;
            
            if (otherUUID != null) {
                String myValue = uuid.toString();
                String otherValue = otherUUID.toString();
                result = myValue.equals(otherValue);
            }
        }
        
        return result;
    }
    
    @Override
    public int hashCode() {
        int hashValue = super.hashCode();
        
        if (name != null)
            hashValue += name.hashCode();
        
        if (uuid != null)
            hashValue += uuid.hashCode();
        
        return hashValue;
    }
    
    // This is specifically used for adding / removing system notification icons
    public int getAlarmNotificationID() {
        int alarmNotificationID = UNKNOWN_ALARM_NOTIFICATION_ID;
        
        if (uuid != null)
            alarmNotificationID = uuid.hashCode();
        
        return alarmNotificationID;
    }
    
    public void acceptRingtone(Context context, Uri ringtoneUri) {
        if (ringtoneUri != null) {
            ringtoneUriString = ringtoneUri.toString();
            ringtoneTitle = RingtoneUtils.getRingtoneTitleFromUri(context, ringtoneUri);
        }
    }
    
    public void clearRingtone() {
        ringtoneUriString = StringUtils.EMPTY;
        ringtoneTitle = StringUtils.EMPTY;
    }
    
    public boolean hasRingtone() {
        boolean result = StringUtils.isNotBlank(ringtoneUriString);
        return result;
    }

    // ================================================================================================================
    // Parcel-related items

    public static final String ALARM_PARCEL_NAME = "alarm";
    public static final String PARCEL_NAME = "name";
    public static final String PARCEL_ENABLED = "enabled";
    public static final String PARCEL_VIBRATE = "vibrate";
    public static final String PARCEL_TRIGGER_TIME = "triggerTime";
    public static final String PARCEL_UUID = "id";
    public static final String PARCEL_ROW_ID = "rowID";
    public static final String PARCEL_RINGTONE_URI = "ringtoneUri";
    public static final String PARCEL_RINGTONE_TITLE = "ringtoneTitle";
    
    public Alarm(Parcel source) {
        Bundle bundle = source.readBundle();
        if (bundle != null) {
            name = bundle.getString(PARCEL_NAME);
            ringtoneUriString = bundle.getString(PARCEL_RINGTONE_URI);
            ringtoneTitle = bundle.getString(PARCEL_RINGTONE_TITLE);
            enabled = bundle.getBoolean(PARCEL_ENABLED);
            vibrate = bundle.getBoolean(PARCEL_VIBRATE);
            triggerTime = bundle.getLong(PARCEL_TRIGGER_TIME);
            rowID = bundle.getLong(PARCEL_ROW_ID);
            
            String uuidString = bundle.getString(PARCEL_UUID);
            if (uuidString != null) {
                uuid = UUID.fromString(uuidString);
            }
        }
    }
    
    public void writeToParcel(Parcel dest, int flags) {
        Bundle bundle = new Bundle();
        
        bundle.putString(PARCEL_NAME, name);
        bundle.putString(PARCEL_RINGTONE_URI, ringtoneUriString);
        bundle.putString(PARCEL_RINGTONE_TITLE, ringtoneTitle);
        bundle.putBoolean(PARCEL_ENABLED, enabled);
        bundle.putBoolean(PARCEL_VIBRATE, vibrate);
        bundle.putLong(PARCEL_TRIGGER_TIME, triggerTime);
        bundle.putLong(PARCEL_ROW_ID, rowID);
        bundle.putString(PARCEL_UUID, uuid.toString());
        
        dest.writeBundle(bundle);
        
    }
    public static final Parcelable.Creator<Alarm> CREATOR = new Parcelable.Creator<Alarm>() {
        public Alarm createFromParcel(Parcel source) {
            return new Alarm(source);
        }
        
        public Alarm[] newArray(int size) {
            return new Alarm[size];
        }
    };
        
}
